package ${package.ServiceImpl};

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ${serviceBPO.clazzPackage}.${serviceBPO.clazzName};
import ${entityDTO.clazzPackage}.${entityDTO.clazzName};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import com.insigma.framework.db.JdbcPageHelper;
import com.insigma.framework.db.PageInfo;
import com.insigma.framework.util.DtoEntityUtil;
import com.insigma.web.support.util.SysFunctionManager;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.mohrss.leaf.core.framework.context.CurrentUser;
<#if serviceBPOImpl.superClazzName??>
import ${serviceBPOImpl.superClazzPackage};
</#if>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;


import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * ${table.comment!} 服务实现类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Service
<#if kotlin>
open class ${serviceBPOImpl.clazzName} : <#if serviceBPO.clazzName??>${serviceBPO.clazzName}</#if> {

}
<#elseif serviceBPOImpl.superClazzName??>
public class ${serviceBPOImpl.clazzName} extends ${serviceBPOImpl.superClazzName} <#if serviceBPO.clazzName??>implements ${serviceBPO.clazzName}</#if> {
<#else>
public class ${serviceBPOImpl.clazzName} <#if serviceBPO.clazzName??>implements ${serviceBPO.clazzName}</#if> {
</#if>
<#if !kotlin>

    @Autowired
    private ${table.mapperName} ${table.mapperName?uncap_first};

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public PageInfo<${entityDTO.clazzName}> queryPageList(${entityDTO.clazzName} ${entityDTO.clazzName?uncap_first}, Integer page, Integer size) {
        Page<${entity}> dpPage = new Page<>(page, size);
        QueryWrapper<${entity}>  wrapper = buildQueryWrapper(${entityDTO.clazzName?uncap_first});
        IPage<${entity}> mapIPage = ${table.mapperName?uncap_first}.page(dpPage, wrapper);
        List<${entity}> records = mapIPage.getRecords();
        List<${entityDTO.clazzName}> list = DtoEntityUtil.trans(records, ${entityDTO.clazzName}.class);
        PageInfo<${entityDTO.clazzName}> pageInfo = new PageInfo<>();
        pageInfo.setTotal(mapIPage.getTotal());
        pageInfo.setData(list);
        return pageInfo;
    }

    @SneakyThrows
    @Override
    public PageInfo<${entityDTO.clazzName}> queryListForExport(${entityDTO.clazzName} ${entityDTO.clazzName?uncap_first}, Integer page, Integer size) {
        Map<String, Object> params = new HashMap<>();
        StringBuffer sql = setQueryForExportSQL(${entityDTO.clazzName?uncap_first}, params);
        JdbcPageHelper jdbcPageHelper = new JdbcPageHelper(jdbcTemplate, page, size, "grid", SysFunctionManager.getFunctionId());
        return jdbcPageHelper.queryPagination(sql.toString(), params, ${entityDTO.clazzName}.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(${entityDTO.clazzName} ${entityDTO.clazzName?uncap_first}) {
        ${entity} bean = DtoEntityUtil.trans(${entityDTO.clazzName?uncap_first}, ${entity}.class);
    <#list table.fields as field>
        <#if field.keyFlag>
        ${field.columnType?lower_case?cap_first} id = bean.get${field.propertyName?cap_first}();
        </#if>
    </#list>
        if (ObjectUtils.isEmpty(id)) { // 新增
            id = IdUtil.getSnowflakeNextIdStr();
        }
        Date now =  new Date();
        CurrentUser currentUser = getCurrentUser();
    <#list table.fields as field>
        <#if field.keyFlag>
        bean.set${field.propertyName?cap_first}(id);
        </#if>
    </#list>
        bean.setCreateBy(currentUser.getUserid());
        bean.setCreateTime(now);
        bean.setUpdateBy(currentUser.getUserid());
        bean.setUpdateTime(now);
        return ${table.mapperName?uncap_first}.insert(bean)>0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBatch(Collection<${entityDTO.clazzName}> datas) {
        if(CollectionUtils.isEmpty(datas)){
            return true;
        }
        boolean flag = false;
        final Date now =  new Date();
        final CurrentUser currentUser = getCurrentUser();
        List<${entity}> insertList = datas.stream()
    <#list table.fields as field>
        <#if field.keyFlag>
            .filter(item->ObjectUtils.isEmpty(item.get${field.propertyName?cap_first}()))
        </#if>
    </#list>
            .map(item->DtoEntityUtil.trans(item, ${entity}.class))
            .peek(item->{
            <#list table.fields as field>
                <#if field.keyFlag>
                item.set${field.propertyName?cap_first}(IdUtil.getSnowflakeNextIdStr());
                </#if>
            </#list>
                item.setCreateBy(currentUser.getUserid());
                item.setCreateTime(now);
                item.setUpdateBy(currentUser.getUserid());
                item.setUpdateTime(now);
            })
            .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(insertList)){
            flag = ${table.mapperName?uncap_first}.insertBatch(insertList);
        }
        List<${entity}> updateList = datas.stream()
    <#list table.fields as field>
        <#if field.keyFlag>
            .filter(item->!ObjectUtils.isEmpty(item.get${field.propertyName?cap_first}()))
        </#if>
    </#list>
            .map(item->DtoEntityUtil.trans(item, ${entity}.class))
            .peek(item->{
                item.setUpdateBy(currentUser.getUserid());
                item.setUpdateTime(now);
            })
            .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(updateList)){
            flag = ${table.mapperName?uncap_first}.updateBatchById(updateList);
        }
        return flag;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateById(${entityDTO.clazzName} ${entityDTO.clazzName?uncap_first}) {
        ${entity} bean = DtoEntityUtil.trans(${entityDTO.clazzName?uncap_first}, ${entity}.class);
        return ${table.mapperName?uncap_first}.updateById(bean)>0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        return ${table.mapperName?uncap_first}.removeById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> ids) {
        return ${table.mapperName?uncap_first}.removeByIds(ids);
    }

    @Override
    public ${entityDTO.clazzName} queryById(Serializable id) {
        ${entity} dp = ${table.mapperName?uncap_first}.selectById(id);
        return DtoEntityUtil.trans(dp, ${entityDTO.clazzName}.class);
    }

    @Override
    public ${entityDTO.clazzName} queryOne(${entityDTO.clazzName} ${entityDTO.clazzName?uncap_first}) {
        QueryWrapper<${entity}> wrapper = new QueryWrapper<>();
    <#list table.fields as field>
        <#if field.keyFlag>
        wrapper.lambda().eq(!ObjectUtils.isEmpty(${entityDTO.clazzName?uncap_first}.get${field.propertyName?cap_first}()), ${entity}::get${field.propertyName?cap_first}, ${entityDTO.clazzName?uncap_first}.get${field.propertyName?cap_first}());
        </#if>
    </#list>
        //查询有没有相同的数据
        ${entity} bean = ${table.mapperName?uncap_first}.selectOne(wrapper);
        return DtoEntityUtil.trans(bean, ${entityDTO.clazzName}.class);
    }

    /**
     * 自定义查询条件
     */
    private QueryWrapper<${entity}> buildQueryWrapper(${entityDTO.clazzName} bo) {
        QueryWrapper<${entity}> lqw = Wrappers.query();
        lqw.lambda()
        <#list entityPO.fields as fieldExtends>
            <#assign field = fieldExtends.field />
            .eq(ObjectUtil.isNotEmpty(bo.get${field.propertyName?cap_first}()), ${entity}::get${field.propertyName?cap_first}, bo.get${field.propertyName?cap_first}())
        </#list>
        ;
        return lqw;
    }

    /**
     * 设置导出功能的查询条件
     * @param queryDTO 查询条件
     * @param params 查询参数
     */
    private StringBuffer setQueryForExportSQL(${entityDTO.clazzName} queryDTO, Map<String, Object> params) {
        StringBuffer sql = new StringBuffer("select * from ${table.name} a where 1=1 ");
    <#list entityDTO.fields as fieldExtends>
        <#assign field = fieldExtends.field />
        if (!ObjectUtils.isEmpty(queryDTO.get${field.propertyName?cap_first}())) {
            sql.append(" and a.${field.columnName} = :${field.propertyName}");
            params.put("${field.propertyName}", queryDTO.get${field.propertyName?cap_first}());
        }
    </#list>
//        if (!ObjectUtils.isEmpty(queryDTO.getName())) {
//            sql.append(" and name like :name");
//            params.put("name", "%" + queryDTO.getName() + "%");
//        }
//        if (!ObjectUtils.isEmpty(queryDTO.getStartTime())) {
//            //查询条件为时间段选项
//            SimpleDateFormat st = new SimpleDateFormat("yyyy-MM-dd");
//            Date oTime = st.parse(queryDTO.getStartTime().split(",")[0]);
//            Date pTime = st.parse(queryDTO.getStartTime().split(",")[1]);
//            sql.append(" and birthday > :startTime and birthday < :endTime");
//            params.put("startTime", oTime);
//            params.put("endTime", pTime);
//        }
        return sql;
    }
}
</#if>